﻿using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Utils.Wpf
{
	public partial class UpDownArrow : UserControl
	{
		#region Attributes
		
		private Visibility _visibility;

		#endregion

		#region Properties
		
        public new Visibility Visibility
        {
            get
            {
            	return _visibility;
            }
            set
            {
                if (value != _visibility)
                {
					this.OnVisibilityChanging(value);
                    _visibility = value;
                    base.Visibility = value;
                }
            }
        }

		#endregion

		#region Dependence Properties

		public static DependencyProperty IsUpProperty = DependencyProperty.Register("IsUp", typeof(bool), typeof(UpDownArrow), new FrameworkPropertyMetadata(OnIsUpPropertyChanged));

		private static void OnIsUpPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
		{
			UpDownArrow control = (UpDownArrow)source;

			if (control.Visibility == Visibility.Visible)
			{
				control.ExecuteAnimation();
			}
		}

		public bool IsUp
		{
			get
			{
				return (bool)base.GetValue(IsUpProperty);
			}
			set
			{
				base.SetValue(IsUpProperty, value);
			}
		}

		public static DependencyProperty UpBorderColorProperty = DependencyProperty.Register("UpBorderColor", typeof(Brush), typeof(UpDownArrow), new FrameworkPropertyMetadata(OnUpBorderColorPropertyChanged));

		private static void OnUpBorderColorPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
		{
			UpDownArrow control = (UpDownArrow)source;

			if (control.IsUp)
			{
				control.Arrow.Stroke = (Brush)e.NewValue;
			}

			ColorAnimation animation = (ColorAnimation)((Storyboard)control.FindResource("UpToDownAnimation")).Children.First(c => c.Name == "UpBorderAnimation");
			animation.From = ((SolidColorBrush)e.NewValue).Color;
			animation = (ColorAnimation)((Storyboard)control.FindResource("DownToUpAnimation")).Children.First(c => c.Name == "DownBorderAnimation");
			animation.To = ((SolidColorBrush)e.NewValue).Color;
		}

		public Brush UpBorderColor
		{
			get
			{
				return (Brush)base.GetValue(UpBorderColorProperty);
			}
			set
			{
				base.SetValue(UpBorderColorProperty, value);
			}
		}

		public static DependencyProperty DownBorderColorProperty = DependencyProperty.Register("DownBorderColor", typeof(Brush), typeof(UpDownArrow), new FrameworkPropertyMetadata(OnDownBorderColorPropertyChanged));

		private static void OnDownBorderColorPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
		{
			UpDownArrow control = (UpDownArrow)source;

			if (!control.IsUp)
			{
				control.Arrow.Stroke = (Brush)e.NewValue;
			}

			ColorAnimation animation = (ColorAnimation)((Storyboard)control.FindResource("UpToDownAnimation")).Children.First(c => c.Name == "UpBorderAnimation");
			animation.To = ((SolidColorBrush)e.NewValue).Color;
			animation = (ColorAnimation)((Storyboard)control.FindResource("DownToUpAnimation")).Children.First(c => c.Name == "DownBorderAnimation");
			animation.From = ((SolidColorBrush)e.NewValue).Color;
		}

		public Brush DownBorderColor
		{
			get
			{
				return (Brush)base.GetValue(DownBorderColorProperty);
			}
			set
			{
				base.SetValue(DownBorderColorProperty, value);
			}
		}

		public static DependencyProperty UpFillColorProperty = DependencyProperty.Register("UpFillColor", typeof(Brush), typeof(UpDownArrow), new FrameworkPropertyMetadata(OnUpFillColorPropertyChanged));

		private static void OnUpFillColorPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
		{
			UpDownArrow control = (UpDownArrow)source;

			if (control.IsUp)
			{
				control.Arrow.Fill = (Brush)e.NewValue;
			}

			ColorAnimation animation = (ColorAnimation)((Storyboard)control.FindResource("UpToDownAnimation")).Children.First(c => c.Name == "UpFillAnimation");
			animation.From = ((SolidColorBrush)e.NewValue).Color;
			animation = (ColorAnimation)((Storyboard)control.FindResource("DownToUpAnimation")).Children.First(c => c.Name == "DownFillAnimation");
			animation.To = ((SolidColorBrush)e.NewValue).Color;
		}

		public Brush UpFillColor
		{
			get
			{
				return (Brush)base.GetValue(UpFillColorProperty);
			}
			set
			{
				base.SetValue(UpFillColorProperty, value);
			}
		}

		public static DependencyProperty DownFillColorProperty = DependencyProperty.Register("DownFillColor", typeof(Brush), typeof(UpDownArrow), new FrameworkPropertyMetadata(OnDownFillColorPropertyChanged));

		private static void OnDownFillColorPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
		{
			UpDownArrow control = (UpDownArrow)source;

			if (!control.IsUp)
			{
				control.Arrow.Fill = (Brush)e.NewValue;
			}

			ColorAnimation animation = (ColorAnimation)((Storyboard)control.FindResource("UpToDownAnimation")).Children.First(c => c.Name == "UpFillAnimation");
			animation.To = ((SolidColorBrush)e.NewValue).Color;
			animation = (ColorAnimation)((Storyboard)control.FindResource("DownToUpAnimation")).Children.First(c => c.Name == "DownFillAnimation");
			animation.From = ((SolidColorBrush)e.NewValue).Color;
		}

		public Brush DownFillColor
		{
			get
			{
				return (Brush)base.GetValue(DownFillColorProperty);
			}
			set
			{
				base.SetValue(DownFillColorProperty, value);
			}
		}

		#endregion

		#region Public Methods

		public UpDownArrow()
		{
			InitializeComponent();
		}

		protected virtual void OnVisibilityChanging(Visibility newValue)
		{
			if (newValue == Visibility.Visible)
			{
				this.ExecuteAnimation();	
			}
		}

		#endregion

		#region Private Methods

		private void ExecuteAnimation	()
		{
			Storyboard storyboard;
			if (this.IsUp)

			{
				storyboard = (Storyboard)this.FindResource("DownToUpAnimation");
			}
			else
			{
				storyboard = (Storyboard)this.FindResource("UpToDownAnimation");
			}

			storyboard.Begin();	
		}

		#endregion


	}
}
